// -----------------------------------------------------------------------
//  <copyright file="AuthorizationExceptionHandler.cs" company="LiuliuSoft">
//      Copyright (c) 2022-2024 DaprPlus. All rights reserved.
//  </copyright>
//  <site>https://dapr.plus</site>
//  <last-editor>郭明锋</last-editor>
//  <last-date>2024/12/8 3:02:06</last-date>
// -----------------------------------------------------------------------

using DaprPlus.AspNetCore.Extensions;
using DaprPlus.AspNetCore.Mvc.Filters;

using Microsoft.AspNetCore.Mvc.Filters;


namespace DaprPlus.Authorization.AspNetCore;

/// <summary>
/// 授权异常处理器
/// </summary>
public class AuthorizationExceptionHandler : ApiResultExceptionHandlerBase
{
    /// <inheritdoc />
    public override int Priority => 200;

    /// <inheritdoc />
    public override bool CanHandle(Exception exception)
    {
        return exception is AuthorizationException;
    }

    /// <inheritdoc />
    public override bool Handle(Exception exception, ActionExecutedContext context)
    {
        if (exception is not AuthorizationException authEx)
        {
            return false;
        }

        // 处理JSON/AJAX请求
        if (context.HttpContext.Request.IsJsonContextType() || context.HttpContext.Request.IsAjaxRequest())
        {
            if (!context.HttpContext.Response.HasStarted)
            {
                var result = ApiResult.FromAuthorizationResult(authEx.AuthorizationResult);
                context.Result = result.ToActionResult();
            }
            context.ExceptionHandled = true;
            return true;
        }

        // 处理非JSON请求，设置HTTP状态码
        var statusCode = authEx.AuthorizationResult.ResultType switch
        {
            AuthorizationStatus.Unauthorized => 401,
            AuthorizationStatus.Forbidden => 403,
            AuthorizationStatus.NotFound => 404,
            _ => 500
        };

        return SetHttpStatusCode(context, statusCode);
    }

    /// <inheritdoc />
    protected override string GetFriendlyMessage(Exception exception)
    {
        // 这个方法在授权异常处理器中不会被调用，因为重写了Handle方法
        return exception.Message;
    }
}
